<template>
  <div class="min-h-200 flex-col items-center gap-y-20">
    <MyToggle v-model="active" :options="tabs" />
    <div v-if="active === 'execute'" v-permission="`execute_duration_sel`" class="execute">
      <div class="card">
        <div class="head">
          <div class="title">项目维度</div>
          <div
            v-permission="`execute_duration_edit`"
            class="edit"
            @click="handleEditProject(data.projectInfo)"
          >
            <n-icon :component="ModeEditOutlined" />
            编辑
          </div>
        </div>
        <div class="info-list">
          <div class="info">
            <div class="label">
              <img class="logo" src="@/assets/icons/prototype.png" />
              原型工期
            </div>
            <v-chart
              :option="data.prototypeOption"
              :loading="data.projectLoading"
              autoresize
              style="height: 140px"
            />
          </div>
          <div class="info">
            <div class="label">
              <img class="logo" src="@/assets/icons/design.png" />
              设计工期
            </div>
            <v-chart
              :option="data.designOption"
              :loading="data.projectLoading"
              autoresize
              style="height: 140px"
            />
          </div>
          <div class="info">
            <div class="label">
              <img class="logo" src="@/assets/icons/develop.png" />
              开发工期
            </div>
            <v-chart
              :option="data.developOption"
              :loading="data.projectLoading"
              autoresize
              style="height: 140px"
            />
          </div>
        </div>
      </div>
      <div class="card">
        <div class="head">
          <div class="title">人员维度</div>
        </div>
        <n-grid :cols="2" :y-gap="30" class="mt-10">
          <n-gi>
            <v-chart
              :option="data.realOption"
              :loading="data.personLoading"
              autoresize
              style="height: 200px"
            />
          </n-gi>
          <n-gi>
            <v-chart
              :option="data.delayOption"
              :loading="data.personLoading"
              autoresize
              style="height: 200px"
            />
          </n-gi>
          <n-gi :span="2">
            <v-chart
              :option="data.durationOption"
              :loading="data.personLoading"
              autoresize
              style="height: 400px"
            />
          </n-gi>
        </n-grid>
      </div>
    </div>
    <Record
      v-if="active === 'process'"
      :id="detail.id"
      :apis="processApis"
      :permission-keys="{
        list: 'process_duration_sel',
        add: 'process_duration_sub',
        edit: 'process_duration_update',
        del: 'process_duration_delete',
      }"
    />
    <MyDrawer ref="$formProject" :model-form="modelProject" @submit="handleSubmitProject">
      <div class="flex-col gap-y-30">
        <div class="flex-col">
          <div class="flex gap-x-8">
            <img class="h-18 w-18" src="@/assets/icons/prototype.png" />
            <div class="font-size-14 color-#030912 font-bold">原型工期</div>
          </div>
          <n-form-item label="评估原型工期" path="estimateMoldDuration">
            <n-input-number
              v-model:value="modelProject.estimateMoldDuration"
              placeholder="请输入数字0-2000以内，小数不超出2位"
              :precision="2"
              :min="0"
              :max="2000"
              clearable
            />
          </n-form-item>
          <n-form-item label="实际原型工期" path="realMoldDuration">
            <n-input-number
              v-model:value="modelProject.realMoldDuration"
              placeholder="请输入数字0-2000以内，小数不超出2位"
              :precision="2"
              :min="0"
              :max="2000"
              clearable
            />
          </n-form-item>
        </div>
        <div class="flex-col">
          <div class="flex gap-x-8">
            <img class="h-18 w-18" src="@/assets/icons/design.png" />
            <div class="font-size-14 color-#030912 font-bold">设计工期</div>
          </div>
          <n-form-item label="评估设计工期" path="estimateDesignDuration">
            <n-input-number
              v-model:value="modelProject.estimateDesignDuration"
              placeholder="请输入数字0-2000以内，小数不超出2位"
              :precision="2"
              :min="0"
              :max="2000"
              clearable
            />
          </n-form-item>
          <n-form-item label="实际设计工期" path="realDesignDuration">
            <n-input-number
              v-model:value="modelProject.realDesignDuration"
              placeholder="请输入数字0-2000以内，小数不超出2位"
              :precision="2"
              :min="0"
              :max="2000"
              clearable
            />
          </n-form-item>
        </div>
        <div class="flex-col">
          <div class="flex gap-x-8">
            <img class="h-18 w-18" src="@/assets/icons/develop.png" />
            <div class="font-size-14 color-#030912 font-bold">开发工期</div>
          </div>
          <n-form-item label="评估开发工期" path="estimateDevelopDuration">
            <n-input-number
              v-model:value="modelProject.estimateDevelopDuration"
              placeholder="请输入数字0-2000以内，小数不超出2位"
              :precision="2"
              :min="0"
              :max="2000"
              clearable
            />
          </n-form-item>
          <n-form-item label="实际开发工期" path="realDevelopDuration">
            <n-input-number
              v-model:value="modelProject.realDevelopDuration"
              placeholder="请输入数字0-2000以内，小数不超出2位"
              :precision="2"
              :min="0"
              :max="2000"
              clearable
              :disabled="true"
            />
          </n-form-item>
          <n-form-item label="安排开发工期" path="arrangeDevelopDuration">
            <n-input-number
              v-model:value="modelProject.arrangeDevelopDuration"
              placeholder="请输入数字0-2000以内，小数不超出2位"
              :precision="2"
              :min="0"
              :max="2000"
              clearable
              :disabled="true"
            />
          </n-form-item>
        </div>
      </div>
    </MyDrawer>
  </div>
</template>
<script setup lang="jsx">
import * as echarts from 'echarts/core'
import {
  TooltipComponent,
  GridComponent,
  LegendComponent,
  TitleComponent,
} from 'echarts/components'
import { BarChart, LineChart, PieChart } from 'echarts/charts'
import { UniversalTransition } from 'echarts/features'
import { CanvasRenderer } from 'echarts/renderers'
import VChart from 'vue-echarts'
import { useCrudPro } from '@/hooks/useCrudPro'
import * as projectApi from '@/api/project'
import { ModeEditOutlined } from '@vicons/material'
import { useAuthTabs } from '@/hooks/useAuthTabs'
import { usePermissionStore } from '@/store'
echarts.use([
  TooltipComponent,
  GridComponent,
  LegendComponent,
  TitleComponent,
  BarChart,
  LineChart,
  CanvasRenderer,
  UniversalTransition,
  PieChart,
])
defineOptions({ name: 'DurationRecord' })
const props = defineProps({
  detail: {
    type: Object,
    default: () => ({}),
  },
})
const processApis = {
  add: projectApi.processRecordAdd,
  list: projectApi.processRecordList,
}

const { tabs, active } = useAuthTabs([
  { label: '执行工期', value: 'execute', key: 'execute_duration' },
  { label: '过程工期', value: 'process', key: 'process_duration' },
])
const { hasPermission } = usePermissionStore()
const data = reactive({
  //项目维度
  projectLoading: false,
  projectInfo: {},
  prototypeOption: {},
  designOption: {},
  developOption: {},
  //人员维度
  personLoading: false,
  personInfo: {},
  realOption: {},
  delayOption: {},
  durationOption: {},
})
const methods = reactive({
  async getDurationByProjectInfo() {
    data.projectLoading = true
    const res = await projectApi.durationByProjectInfo({ projectId: props.detail.id })
    const {
      estimateMoldDuration = 0,
      realMoldDuration = 0,
      estimateDesignDuration = 0,
      realDesignDuration = 0,
      estimateDevelopDuration = 0,
      realDevelopDuration = 0,
      arrangeDevelopDuration = 0,
    } = res.data
    data.projectInfo = res.data
    data.prototypeOption = methods.generateBarOption([
      {
        name: '评估工期',
        value: estimateMoldDuration,
      },
      {
        name: '实际工期',
        value: realMoldDuration,
      },
    ])
    data.designOption = methods.generateBarOption([
      {
        name: '评估工期',
        value: estimateDesignDuration,
      },
      {
        name: '实际工期',
        value: realDesignDuration,
      },
    ])
    data.developOption = methods.generateBarOption([
      {
        name: '评估工期',
        value: estimateDevelopDuration,
      },
      {
        name: '实际工期',
        value: realDevelopDuration,
      },
      {
        name: '系统排期',
        value: arrangeDevelopDuration,
      },
    ])
    data.projectLoading = false
  },
  generateBarOption(data) {
    const colors = ['#4D73F0', '#4BD6B9', '#FAAD14']
    return {
      grid: {
        left: 10,
        right: 30,
        top: 16,
        bottom: 16,
        containLabel: true,
      },
      xAxis: [
        {
          splitLine: {
            show: false,
          },
          axisLabel: { color: '#686F7C' },
          type: 'value',
          show: false,
        },
      ],
      yAxis: [
        {
          type: 'category',
          splitLine: {
            show: false,
          },
          axisLine: {
            //y轴
            show: false,
          },
          axisTick: {
            show: false,
          },
          inverse: true,
          data: data.map((item) => item.name),
          axisLabel: {
            color: '#686F7C',
            fontSize: 12,
            interval: 0,
          },
        },
      ],
      series: [
        {
          name: 'bar',
          type: 'bar',
          symbolSize: 0,
          showSymbol: false,
          barWidth: 24, // 柱子宽度
          label: {
            show: true,
            position: 'insideLeft', // 位置
            color: '#000',
            fontSize: 12,
            distance: 5, // 距离
          }, // 柱子上方的数值
          itemStyle: {
            color({ dataIndex }) {
              return colors[dataIndex]
            },
          },
          data: data.map((item) => item.value),
        },
      ],
    }
  },
  async getDurationByPersonInfo() {
    data.personLoading = true
    const res = await projectApi.durationByPersonInfo(props.detail.id)
    data.realOption = methods.generatePieOption(
      '研发人员实际总工期分布',
      res.data.map(({ duration, name }) => ({ name, value: duration }))
    )
    data.delayOption = methods.generatePieOption(
      '研发人员延期情况分布',
      res.data.map(({ extension, name }) => ({ name, value: extension }))
    )
    data.durationOption = methods.generateColumnOption(
      '研发人员安排工期与延长工期分布',
      res.data.map(({ extension, reality, name }) => ({ name, value1: extension, value2: reality }))
    )
    data.personLoading = false
  },
  generatePieOption(title, data) {
    return {
      title: {
        text: title,
        left: 0,
        textStyle: {
          color: '#3A3E45',
          fontSize: 14,
        },
      },
      legend: {
        orient: 'vertical',
        top: 'center',
        right: 30,
        icon: 'roundRect',
        textStyle: {
          align: 'left',
          verticalAlign: 'middle',
          rich: {
            name: {
              color: 'rgba(0,0,0,0.5)',
              fontSize: 10,
            },
            value: {
              color: 'rgba(0,0,0,0.5)',
              fontSize: 10,
            },
            rate: {
              color: 'rgba(0,0,0,0.9)',
              fontSize: 10,
            },
          },
        },
        data: data,
        formatter: (name) => {
          if (data.length) {
            const item = data.filter((item) => item.name === name)[0]
            return `{name|${name}：}{value| ${item.value}}`
          }
        },
      },
      series: [
        {
          name: '访问来源',
          type: 'pie',
          radius: ['50%', '80%'],
          label: {
            show: false,
            position: 'center',
          },
          labelLine: {
            show: false,
          },
          data: data,
          center: ['25%', '55%'],
        },
      ],
    }
  },
  generateColumnOption(title, data) {
    return {
      title: {
        text: title,
        left: 0,
        textStyle: {
          color: '#3A3E45',
          fontSize: 14,
        },
      },
      tooltip: {
        trigger: 'axis',
        axisPointer: {
          // 坐标轴指示器，坐标轴触发有效
          type: 'shadow', // 默认为直线，可选为：'line' | 'shadow'
        },
      },
      legend: {
        top: 0,
        right: 30,
        icon: 'roundRect',
        textStyle: {
          align: 'left',
          verticalAlign: 'middle',
          rich: {
            name: {
              color: 'rgba(0,0,0,0.5)',
              fontSize: 10,
            },
            value: {
              color: 'rgba(0,0,0,0.5)',
              fontSize: 10,
            },
            rate: {
              color: 'rgba(0,0,0,0.9)',
              fontSize: 10,
            },
          },
        },
        data: ['延长工期', '安排工期'],
      },
      xAxis: [
        {
          type: 'category',
          data: data.map((item) => item.name),
        },
        {
          type: 'category',
          axisLine: {
            show: false,
          },
          axisTick: {
            show: false,
          },
          axisLabel: {
            show: false,
          },
          splitArea: {
            show: false,
          },
          splitLine: {
            show: false,
          },
          data: data.map((item) => item.name),
        },
      ],
      yAxis: {
        type: 'value',
        axisLabel: {
          color: '#000000',
          textStyle: {
            fontSize: 12,
          },
        },
        splitLine: {
          show: true,
          lineStyle: {
            type: 'dashed',
            color: '#E8E8E8',
          },
        },
        axisTick: {
          show: false,
        },
        axisLine: {
          show: false,
        },
      },
      series: [
        {
          name: '安排工期',
          type: 'bar',
          xAxisIndex: 1,
          itemStyle: {
            color: '#4D73F0',
          },
          barWidth: '24',
          data: data.map((item) => item.value2),
        },
        {
          name: '延长工期',
          type: 'bar',
          itemStyle: {
            color: '#4BD6B9',
          },
          barWidth: '24',
          data: data.map((item) => item.value1),
        },
      ],
    }
  },
})
watch(
  () => props.detail.id,
  (val) => {
    if (val && hasPermission('execute_duration_sel')) {
      methods.getDurationByProjectInfo()
      methods.getDurationByPersonInfo()
    }
  },
  {
    immediate: true,
  }
)

const {
  model: modelProject,
  $form: $formProject,
  handleEdit: handleEditProject,
  handleSubmit: handleSubmitProject,
} = useCrudPro({
  name: '执行工期',
  initForm: {
    estimateMoldDuration: null,
    realMoldDuration: null,
    estimateDesignDuration: null,
    realDesignDuration: null,
    estimateDevelopDuration: null,
    realDevelopDuration: null,
    arrangeDevelopDuration: null,
  },
  apis: {
    edit: (data) => projectApi.durationByProjectEdit({ ...data, projectId: props.detail.id }),
  },
  formatParams(params) {
    return Object.fromEntries(
      Object.entries(params).map(([key, value]) => [
        key,
        typeof value === 'number' ? value.toFixed(2) : value,
      ])
    )
  },
  handleChange() {
    $message.success('编辑执行工期成功！')
    methods.getDurationByProjectInfo()
  },
})
</script>
<style lang="scss" scoped>
.execute {
  display: flex;
  width: 100%;
  column-gap: 20px;
  .card {
    flex: 1;
    padding: 24px;
    border-radius: 4px;
    border: 1px solid #e7eaf0;
    min-height: 600px;
    .head {
      display: flex;
      align-items: center;
      justify-content: space-between;
      .title {
        font-size: 16px;
        color: #3a3e45;
        font-weight: bold;
      }
      .edit {
        display: flex;
        align-items: center;
        column-gap: 4px;
        color: #0a56d8;
        cursor: pointer;
        height: 22px;
        background: #f4f5f7;
        border-radius: 4px;
        padding: 0 8px;
      }
    }
    .info-list {
      margin-top: 30px;
      display: flex;
      flex-direction: column;
      gap: 60px;
      .info {
        display: flex;
        flex-direction: column;
        gap: 30px;
        .label {
          display: flex;
          align-items: center;
          gap: 10px;
          color: #3a3e45;
          font-size: 14px;
          .logo {
            width: 18px;
            height: 18px;
          }
        }
      }
    }
  }
}
</style>
